

package retegas_java;
 import java.util.*;


class CapacitaSuperataException extends Exception{
}
/*
* Per prima cosa si deve definire una classe che rappresenta una
* singola linea per il trasporto del gas.
* Ogni linea e' rappresentata da le citta di origine e destinazione
* dalla sua capacita' massima e dalla capacita' attualmente in uso
* (che deve essere <= della capacita' massima).
* Le citta' sono rappresentate da stringhe e le capacita' da interi.
*
* La classe Linea deve contenere (almeno) i seguenti metodi:
*
*/

class Linea {
    String orig,desti;
    int max_cap,usocap;


  /*
  * Costruttore
  * Linea(String origine, String dest, int maxcap)
  * crea una nuova linea dalla citta' origine a alla citta
  * dest con capacita' massima maxcap, e capacita' in uso uguale a zero
  */
  Linea(String origine, String dest, int maxcap){
      orig=origine;
      desti=dest;
      max_cap=maxcap;
      usocap=0;
  }
  /* int usa(int c)
  * Tenta di usare capacita' c della linea this.
  * Se la capacita' disponibile e' minore di c lancia l'eccezione
  * CapacitaSuperataException (che dovete definire come sottoclasse di
  * Exception); se invece la capacita' disponibile e' >=c
  * impiega la capacita' c e restituisce la capacita' disponbile
  * dopo aver usato la capacita' c [in altri parole se la capacita'
  * ancora disponbile della linea era 10 e chiedo di usare 4, la capacita'
  * disponbile diventa 6, e il metodo deve restituire 6.
  */
    int usa(int c) throws CapacitaSuperataException{
        if (max_cap-usocap<c){
            throw new CapacitaSuperataException();
        }
        usocap+=c;
        return max_cap-usocap;
    }
  /* public String toString()
  * restituisce una stringa contenenete l'origine e la destinazione della
  * linea, la capacita' attualmente in uso e la capacita' totale
  * della linea
  */
    @Override
  public String toString(){
      return orig + "--> " + desti + usocap + "(" + max_cap +  ")";
  }

}


/* La classe Rete rappresenta un'azienda di distribuzione del gas
* Dal nostro punto di vista la Rete e' semplicemente un insieme
* di linee e quindi la classe dovra' sicuramente avere una
* struttura che contiene tutte le Linee che ad appartengono alla Rete.
* Inoltre consiglio di mantenere la collezione di tutte le citta'
* che sono servite dalla rete (cioe' che sono origine o destinazione
* di una Linea).
*
* La classe Rete deve contenere (almeno) i seguenti metodi:
*/
class Copiacittà implements Comparable<Copiacittà>{
    String orig1,desti1;
    int usocap1;

    Copiacittà(String origine, String dest, int usocap2){
      orig1=origine;
      desti1=dest;
      usocap1=usocap2;
    }
    public int compareTo(Copiacittà i){
        if (i.usocap1 < usocap1)
            return -1;
        if (i.usocap1 == usocap1)
            return 0;
           
            return 1;
    }

           public boolean equals(Object x){
               Copiacittà a=(Copiacittà) x;
               return orig1.equals(a.orig1) && desti1.equals(a.desti1) && usocap1==a.usocap1 ;
           }

           @Override
  public String toString(){
      return orig1 + "--> " + desti1 + usocap1;
  }
}
class Rete {
        List<Linea> rete;
        Set<String> città;
        List<Copiacittà> copia;
    /* costruttore:
    * Rete()
    * crea una nuova rete inzialmente senza nessuna linea
    */
  Rete(){
      rete=new ArrayList<Linea>();
      città=new HashSet<String>();
  }

    /*
    * void aggiungi_linea(Linea x)
    * aggiunge la linea x alla rete
    */
    void aggiungi_linea(Linea x){
        rete.add(x);
        città.add(x.orig);
        città.add(x.desti);
    }


    /* String toString()
    * restituisce una stringa contenente l'elenco delle linee della rete
    * separate da "\n", ogni linea deve essere rappresentata con il
    * relativo toString. Al termine dell'elenco deve essere ripostata
    * la quantita' totale di gas trasportata dalla rete (cioe' la
    * somma delle capacita' in uso di tutte le linee della rete).
    * */


    @Override
    public String toString(){
        String s="";
        int x=0;
        for (Linea i:rete){
            s+= i+ "\n";
            x+=i.usocap;
        }
       return s + "\n" + x + "\n";
     }

    /* String citta_servite()
    * restituisce una stringa contenente l'elenco delle citta
    * servite dalla rete (in un ordine arbitrario) separate da "\n",
    * Al termine dell'elenco deve essere riportato
    * il numero di citta servite dalla rete (cioe' origine o destinazione
    * di una linea).
    * */

    String citta_servite(){
        String s="";
        int c;
        for (String i:città){
            s+= i + "\n";
         }
        return s + città.size();
    }


    /* int totale_trasportato(String c1, String c2)
    * Restituisce la quantita' di gas trasportato dalla citta' c1
    * alla citta' c2 (in altre parole la somma della capacita' in uso
    * da ogni linea da c1 a c2).
    * */

    int totale_trasportato(String c1, String c2){
        int tot=0;
        for (Linea i:rete){
            if (i.orig.equals(c1) && i.desti.equals(c2))
             tot+=i.usocap;
            }
       return tot;
    }


    /* boolean trasporta(String c1, String c2, int c)
    *
    * Considera tutte le linee da c1 a c2. Per ognuna di queste linee
    * prova ad utilizzare la capacita' c utilizzando il metodo usa().
    * Se usa() lancia l'eccezione CapacitaSuperataException cerca
    * altre linee tra c1 e c2, se non ci sono altre linee il metodo
    * restiuisce False. Se una chiamata a usa() non lancia l'eccezione
    * CapacitaSuperataException vuol dire che alla linea e' stata
    * assegnata la capacita' c, e il metodo restiuisce True.
    */
    boolean trasporta(String c1, String c2, int c) throws CapacitaSuperataException{
        for (Linea i:rete){
            if (i.orig.equals(c1) && i.desti.equals(c2))
             try {
            i.usa(c);
            return true;
            }
            catch(CapacitaSuperataException e) {
        }
    }
    return false;
    }

    /* String elenca_coppie()
    * Restituisce una stringa contenente l'elenco di tutte
    * le coppie ordinate di citta' servite dalla rete (separate da \n
    * in modo che ne venga una per linea). Per ogni
    * coppia deve essere riportata la quantita' di gas trasportato
    * dalla prima citta' alla seconda (questo totale e' quello
    * restituito dalla funzione totale_trasportato()).
    * IMPORTANTE: l'elenco di coppie di citta' deve essere ordinato
    * per quantita' di gas decrescente. Ad esempio, se le citta' servite
    * sono Alessandria Asti e genova, l'output potrebbe essere qualcosa del
    * tipo:
    *    Alessandria -> Asti    23
    *    Genova -> Alessandria  15
    *    Asti -> Alessandria    11
    *    Alessandria -> Genova  0
    *    Asti -> Genova          0
    *    Genova -> Asti          0
    * (vedere anche gli altri esempi piu' sotto).
    *
    * Per realizzare questo metodo si consiglia fortemente di definire
    * una classe CoppiaCitta che possa rappresentare una coppia di
    * citta' e la quantita' di gas trasportato tra esse. All'interno di
    * questa classe si definisca un metodo compareTo() che date due
    * CoppieCitta confronti la quantita' di gas tra esse trasportato.
    * A questo punto per realizzare elenca coppie e' sufficiente creare
    * una lista contenente tutte le coppie di citta', ordinarla con
    * Collections.sort(), e creare la stringa risultato.
    * */
    String elenca_coppie_citta(){
        String a="";
        Copiacittà temp= null;
        copia= new ArrayList<Copiacittà>();
        for (Linea i:rete){
           temp=(new Copiacittà(i.orig,i.desti,totale_trasportato(i.orig,i.desti)));
          if (copia.contains(temp));
            else
             copia.add(temp);
            }
       Collections.sort(copia);
      for (Copiacittà c:copia){
          a+= c.orig1 +  "--> "  + c.desti1 + c.usocap1 + "\n";
      }
      return a;
    }


}

/* A questo punto dovete riscrivere tutto in Ruby. Ovviamente la parte
* Ruby non deve essere la semplice traduzione di Java: se in Ruby
* ci sono scorciatoie siete incoraggiati/e ad usarle (ad esempio
* in Ruby elenca_coppie_citta non richiede la classe CoppieCitta) */


/* Per verificare la correttezza del vostro codice Java potete utilizzare
* il metodo main della classe insieme che dovrebbe produrre un output simile
* a quello riportato in fondo a questo file. */



public class Main {


    public static void main(String[] args) throws CapacitaSuperataException {

        System.out.println("===== Inizio test ======");
        System.out.println("---- test linee ----");
        Linea alat1 = new Linea("Alessandria", "Asti", 30);
        Linea alat2 = new Linea("Alessandria", "Asti", 40);
        Linea atal1 = new Linea("Asti", "Alessandria", 25);
        Linea atal2 = new Linea("Asti", "Alessandria", 50);
        System.out.println(alat1.usa(24));
        try {
            alat1.usa(10);
            System.out.println("Errore: eccezione non lanciata");
        }
        catch(CapacitaSuperataException e) {
            System.out.println("Eccezione OK");
        }
        System.out.println(alat2.usa(25));
        try {
            atal1.usa(100);
            System.out.println("Errore: eccezione non lanciata");
        }
        catch(CapacitaSuperataException e) {
            System.out.println("Eccezione OK");
        }
        System.out.println(alat1);
        System.out.println(alat2);
        System.out.println(atal1);
        System.out.println(atal2);
        Linea alge1 = new Linea("Alessandria", "Genova", 90);
        Linea alge2 = new Linea("Alessandria", "Genova", 60);
        System.out.println(alge2.usa(10));
        System.out.println(alge2.usa(12));
        System.out.println(alge2);
    

        System.out.println("---- test creazione rete ----");
        Rete alegas = new Rete();
        alegas.aggiungi_linea(alat1);
        alegas.aggiungi_linea(alat2);
        System.out.println(alegas);
        System.out.println("---");
        alegas.aggiungi_linea(atal1);
        alegas.aggiungi_linea(atal2);
        alegas.aggiungi_linea(alge1);
        alegas.aggiungi_linea(alge2);
        System.out.println(alegas);
        System.out.println("---");
    
        alegas.aggiungi_linea(new Linea("Tortona", "Alessandria", 16));
        System.out.println(alegas.citta_servite());
        System.out.println("-- (l'ordine dell'elenco qui sopra puo' variare) --");

        System.out.println("------ test totale_trasportato e trasporta -----");
        System.out.println(alegas.totale_trasportato("Alessandria","Asti"));
        System.out.println(alegas.totale_trasportato("Bololgna","Asti"));
        System.out.println(alegas.totale_trasportato("Genova","Asti"));
        System.out.println(alegas.totale_trasportato("Alessandria","Genova"));
        System.out.println(alegas.totale_trasportato("Asti","Alessandria"));
        System.out.println("---");
        System.out.println(alegas.trasporta("Asti","Torino",20));
        System.out.println(alegas.trasporta("Asti","Alessandria",20));
        System.out.println(alegas.trasporta("Asti","Alessandria",100));
        System.out.println(alegas.totale_trasportato("Asti","Alessandria"));
        System.out.println(alegas.trasporta("Alessandria","Asti",10));
        System.out.println(alegas.totale_trasportato("Alessandria","Asti"));
        System.out.println(alegas);

        System.out.println("------ test elenca coppie -----");
        System.out.println(alegas.elenca_coppie_citta());
        System.out.println("---");
        System.out.println(alegas.trasporta("Tortona","Alessandria",11));
        System.out.println(alegas.trasporta("Asti","Alessandria",9));
        System.out.println(alegas.elenca_coppie_citta());
        System.out.println("===== Fine test ======");
    }

}

/*

    ===== Inizio test ======
    ---- test linee ----
    6
    Eccezione OK
    15
    Eccezione OK
    Alessandria --> Asti 24 (30)
    Alessandria --> Asti 25 (40)
    Asti --> Alessandria 0 (25)
    Asti --> Alessandria 0 (50)
    50
    38
    Alessandria --> Genova 22 (60)
    ---- test creazione rete ----
    Alessandria --> Asti 24 (30)
    Alessandria --> Asti 25 (40)
    49
    ---
    Alessandria --> Asti 24 (30)
    Alessandria --> Asti 25 (40)
    Asti --> Alessandria 0 (25)
    Asti --> Alessandria 0 (50)
    Alessandria --> Genova 0 (90)
    Alessandria --> Genova 22 (60)
    71
    ---
    Alessandria
    Genova
    Tortona
    Asti
    4
    -- (l'ordine dell'elenco qui sopra puo' variare) --
    ------ test totale_trasportato e trasporta -----
    49
    0
    0
    22
    0
    ---
    false
    true
    false
    20
    true
    59
    Alessandria --> Asti 24 (30)
    Alessandria --> Asti 35 (40)
    Asti --> Alessandria 20 (25)
    Asti --> Alessandria 0 (50)
    Alessandria --> Genova 0 (90)
    Alessandria --> Genova 22 (60)
    Tortona --> Alessandria 0 (16)
    101
    ------ test elenca coppie -----
    Alessandria --> Asti  59
    Alessandria --> Genova  22
    Asti --> Alessandria  20
    Alessandria --> Tortona  0
    Genova --> Alessandria  0
    Genova --> Tortona  0
    Genova --> Asti  0
    Tortona --> Alessandria  0
    Tortona --> Genova  0
    Tortona --> Asti  0
    Asti --> Genova  0
    Asti --> Tortona  0

    ---
    true
    true
    Alessandria --> Asti  59
    Asti --> Alessandria  29
    Alessandria --> Genova  22
    Tortona --> Alessandria  11
    Alessandria --> Tortona  0
    Genova --> Alessandria  0
    Genova --> Tortona  0
    Genova --> Asti  0
    Tortona --> Genova  0
    Tortona --> Asti  0
    Asti --> Genova  0
    Asti --> Tortona  0

    ===== Fine test ======


*/

